package com.yfqy.app.modules.order.builder;

import cn.hutool.core.bean.BeanUtil;
import com.yfqy.app.configure.Idgenerator.SnowflakeIdGenerator;
import com.yfqy.app.constant.GeneralConstants;
import com.yfqy.app.constant.OrderConstants;
import com.yfqy.app.constant.RedisKeyConstants;
import com.yfqy.app.constant.SystemConfigConstants;
import com.yfqy.app.domain.entity.CustomerAddress;
import com.yfqy.app.enums.OrderStatus;
import com.yfqy.app.modules.order.context.OrderBuilderContext;
import com.yfqy.app.modules.order.dto.AutoCancelDTO;
import com.yfqy.app.modules.order.dto.OrderAddressDTO;
import com.yfqy.app.modules.order.dto.OrderAmountDTO;
import com.yfqy.app.modules.order.dto.OrderCreateRequest;
import com.yfqy.app.modules.order.dto.OrderExtendDTO;
import com.yfqy.app.modules.order.dto.OrderInfoDTO;
import com.yfqy.app.modules.order.dto.OrderItemDTO;
import com.yfqy.app.modules.system.service.SystemConfigService;
import com.yfqy.app.util.JSON;
import org.redisson.api.RAtomicLong;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;

@Component
public class OrderInfoBuilder {

    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
    private static final int PAY_EXPIRE_TIME_MINUTES = 10;
    private static final long MILLIS_PER_MINUTE = 60 * 1000L;

    @Autowired
    @Qualifier("singleRedisClient")
    private RedissonClient redissonClient;
    @Autowired
    private SnowflakeIdGenerator idGenerator;
    @Autowired
    private OrderItemBuilder orderItemBuilder;
    @Autowired
    private SystemConfigService systemConfigService;


    public OrderInfoDTO buildOrder(OrderCreateRequest createRequest, OrderAmountDTO orderAmount) {
        // 生成订单序号
        RAtomicLong orderSequence = redissonClient.getAtomicLong(RedisKeyConstants.ORDER_NO_INCR);
        long sequenceNumber = orderSequence.getAndIncrement();
        if (sequenceNumber >= OrderConstants.MAX_ORDER_SEQUENCE) {
            orderSequence.set(OrderConstants.INITIAL_SEQUENCE);
        }
        String orderSequenceNumber = String.format("%03d", sequenceNumber);

        // 构建订单主信息
        OrderInfoDTO order = new OrderInfoDTO();
        order.setId(idGenerator.nextId());
        order.setOrderNo("ORD" + LocalDateTime.now().format(TIME_FORMATTER) + orderSequenceNumber);
        order.setOrderType(createRequest.getOrderType());
        order.setTotalAmount(orderAmount.getTotalAmount());
        order.setPaymentAmount(orderAmount.getPaymentAmount());
        order.setDiscountAmount(orderAmount.getDiscountAmount());
        order.setPointAmount(orderAmount.getPointAmount());
        order.setPoints(orderAmount.getPoints());
        order.setFreightAmount(orderAmount.getFreightAmount());
        order.setUserId(createRequest.getUserId());
        order.setOrderStatus(OrderStatus.PENDING_PAYMENT.getStatus());
        order.setPromotionId(createRequest.getPromotionId() != null ? createRequest.getPromotionId() : GeneralConstants._L1);
        order.setRemark(createRequest.getRemark());
        OrderExtendDTO orderExtendDTO = new OrderExtendDTO();
        orderExtendDTO.setBeforeStatus(OrderStatus.PENDING_PAYMENT.getStatus());
        order.setExtend(JSON.stringify(orderExtendDTO));
        // 查询订单超时时间
        String config = systemConfigService.getConfigValue(
                SystemConfigConstants.CONFIG_GROUP_ORDER,
                SystemConfigConstants.CONFIG_KEY_CANCEL_TIMEOUT
        );
        AutoCancelDTO cancelDTO = JSON.convert(config, AutoCancelDTO.class);
        long minutes = cancelDTO != null ? cancelDTO.getMinutes() : PAY_EXPIRE_TIME_MINUTES;
        order.setPayExpireTime(calculateExpireDate(minutes * MILLIS_PER_MINUTE));

        // 订单商品信息
        List<OrderItemDTO> orderItemDTOS = orderItemBuilder.buildItems(
                createRequest.getItems(),
                createRequest.getPromotionId(),
                orderAmount,
                order.getId()
        );
        order.setOrderItems(orderItemDTOS);

        // 订单发货地址
        CustomerAddress customerAddress = (CustomerAddress) OrderBuilderContext.getValue(OrderConstants.ORDER_ADDRESS);
        OrderAddressDTO orderAddressDTO = BeanUtil.toBean(customerAddress, OrderAddressDTO.class);
        orderAddressDTO.setId(idGenerator.nextId());
        orderAddressDTO.setOrderId(order.getId());
        order.setOrderAddressDTO(orderAddressDTO);

        return order;
    }

    private Date calculateExpireDate(Long expireTimeMillis) {
        return Date.from(Instant.now().plusMillis(expireTimeMillis));
    }
}
